package com.yimiyisu.contract_cust.controller;

import com.google.gson.JsonObject;
import com.yimiyisu.contract_cust.constant.IText_CSS;
import com.yimiyisu.contract_cust.domain.CodeRulesDO;
import com.yimiyisu.contract_cust.domain.ContractDO;
import com.yimiyisu.contract_cust.domain.FieldDO;
import com.yimiyisu.contract_cust.domain.MaterialDO;
import com.yimiyisu.contract_cust.event.model.ContractExportEventModel;
import com.yimiyisu.contract_cust.kit.CodeKit;
import com.yimiyisu.contract_cust.kit.HtmlToPdfKit;
import com.zen.ZenController;
import com.zen.ZenData;
import com.zen.ZenEngine;
import com.zen.ZenResult;
import com.zen.annotation.AccessRole;
import com.zen.annotation.Inject;
import com.zen.enums.ZenRole;
import com.zen.kit.*;

import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@AccessRole(ZenRole.ADMIN)
public class Contract extends ZenController {
    @Inject
    private ZenEngine zenEngine;

    /**
     * 添加合同编号
     */
    public ZenResult addContract(ZenData data) {
        Map<String, Object> template = data.getAsMap("templateId");
        int type = (int) Double.parseDouble(template.get("type").toString());
        ZenResult zenResult;
        if (type == 1) {
            data.put("templateId", template.get("id").toString());
            data.remove("marTemplate");
            zenResult = zenEngine.execute("get/template", ZenData.create(data).put("id", data.get("templateId")));
        } else {
            data.put("marTemplate", template.get("id").toString());
            data.remove("templateId");
            zenResult = zenEngine.execute("get/mar_template", ZenData.create(data).put("id", data.get("marTemplate")));
        }
        if (zenResult.isEmpty()) return ZenResult.fail("模版不存在");
        ContractDO contractDO = zenResult.asEntity(ContractDO.class);
        if (StringKit.isNotEmpty(contractDO.getContext())) data.put("context", contractDO.getContext());
        if (contractDO.getField() != null && !contractDO.getField().isEmpty()) data.put("field", contractDO.getField());

        String rulesId = data.get("rules");
        ZenResult codeResult = zenEngine.execute("get/code", ZenData.create("id", rulesId));
        CodeRulesDO rules = codeResult.get("rules", CodeRulesDO.class);
        String code = CodeKit.generateCode(rules);
        data.put("code", code);
        if ("2".equals(data.get("inorout"))) {
            data.put("receivable", data.get("total"));
        } else {
            data.put("payable", data.get("total"));
        }
        zenEngine.execute("put/contract", data);
        return ZenResult.success();
    }

    /**
     * 生成模版
     */
    public ZenResult template(ZenData data) {
        ZenData zenData = ZenData.create(data);
        zenData.put("title", data.get("title"));
        if (!data.isEmpty("context")) zenData.put("context", data.get("context"));
        if (!data.isEmpty("field")) zenData.put("field", data.getAsList("field",Map.class));
        if (!data.isEmpty("categoryId")) {
            String[] categoryIds = data.getList("categoryId");
            List<JsonObject> jsonObjects = zenEngine.selectByIds("category", List.of(categoryIds));
            for (JsonObject jsonObject : jsonObjects) {
                if (jsonObject.get("isLeaf").getAsInt() == 1) {
                    zenData.put("categoryId", jsonObject.get("id"));
                }
            }
            zenEngine.execute("put/template", zenData);
        } else zenEngine.execute("put/template", zenData);
        return ZenResult.success("模版添加成功");
    }

    /**
     * pdf导出
     */
    public ZenResult pdfExport(ZenData data) {
        String context = data.get("context");
        String title = data.get("title");
        ContractExportEventModel contractExportEventModel = new ContractExportEventModel();

        // 创建导出任务
        ZenResult putExportResult = zenEngine.execute("put/export_task", ZenData.create(data).put("tab", 1));
        String exportTaskId = putExportResult.get("id");

        // 调用异步任务
        contractExportEventModel.setTaskId(exportTaskId);
        contractExportEventModel.setContext(context);
        contractExportEventModel.setTitle(title);
        EventKit.trigger(contractExportEventModel);
        return ZenResult.success("导出PDF成功，请前往导出管理下载");
    }

    // 下载导出的Excel文件
    public ZenResult upload(ZenData data) {
        // 根据路径获取cdn url
        String path = data.get("path");
        String url = UploadKit.getURL(path);
        return ZenResult.success().setData(url);
    }

    /**
     * 提交审批
     */
    public ZenResult submit(ZenData data) {
        data.put("status", 2);
        data.put("stage", 2);
        zenEngine.execute("patch/contract", data);
        ZenData processData = ZenData.create(data);
        processData.put("initiator", data.getUid());
        processData.put("handler", data.getUid());
        processData.put("type", 1);
        processData.put("status", 1);
        processData.put("contractId", data.get("id"));
        zenEngine.execute("put/process", processData);
        return ZenResult.success();
    }

    /**
     * 合同审批
     */
    public ZenResult permission(ZenData data) {
        Map<String, String> permission = data.get("permission", Map.class);
        String status = permission.get("status");
        String explain = permission.get("explain");
        if ("1".equals(status)) {
            data.put("status", 4);
            data.put("stage", 3);
        } else {
            data.put("status", 3);
            data.put("stage", 2);
        }
        zenEngine.execute("patch/contract", data);
        ZenData processData = ZenData.create(data);
        processData.put("handler", data.getUid());
        processData.put("type", 1);
        processData.put("status", status);
        processData.put("explain", explain);
        processData.put("contractId", data.get("id"));
        zenEngine.execute("put/process", processData);
        return ZenResult.success();
    }

    /**
     * 合同盖章
     */
    public ZenResult sign(ZenData data) {
        Map<String, String> sign = data.get("sign", Map.class);
        String status = sign.get("status");
        String explain = sign.get("explain");
        if ("1".equals(status)) {
            data.put("status", 6);
            data.put("stage", 4);
        } else {
            data.put("status", 5);
            data.put("stage", 3);
        }
        zenEngine.execute("patch/contract", data);
        ZenData processData = ZenData.create(data);
        processData.put("handler", data.getUid());
        processData.put("type", 2);
        processData.put("status", status);
        processData.put("explain", explain);
        processData.put("contractId", data.get("id"));
        zenEngine.execute("put/process", processData);
        return ZenResult.success();
    }

    /**
     * 合同归档
     */
    public ZenResult archive(ZenData data) {
        Map<String, String> permission = data.get("permission", Map.class);
        String status = permission.get("status");
        String explain = data.get("explain");
        if ("1".equals(status)) {
            data.put("status", 8);
            data.put("stage", 5);
        } else {
            data.put("status", 7);
            data.put("stage", 4);
        }
        data.put("performStatus", 1);
        zenEngine.execute("patch/contract", data);
        ZenData processData = ZenData.create(data);
        processData.put("handler", data.getUid());
        processData.put("type", 3);
        processData.put("status", status);
        processData.put("explain", explain);
        processData.put("contractId", data.get("id"));
        zenEngine.execute("put/process", processData);
        return ZenResult.success();
    }

    /**
     * 合同完结
     */
    public ZenResult finish(ZenData data) {
        data.put("status", 9);
        data.put("stage", 6);
        zenEngine.execute("patch/contract", data);
        return ZenResult.success();
    }

    /**
     * 下载附件
     */
    public ZenResult download(ZenData data) {
        ZenResult result = zenEngine.execute("get/attachment", ZenData.create("id", data.get("id")));
        List<String> manager = result.getAsStringList("manager");
        if (!manager.contains(data.getUid())) {
            return ZenResult.fail("只有附件管理员可以下载");
        }
        Map<String, Object> file = result.getMap("file");
        String url = UploadKit.getURL((String) file.get("path"));
        System.out.println(url);
        return ZenResult.success().setData(url);
    }

    /**
     * 合同元素预览
     */
    public ZenResult preview(ZenData data) {
        ZenResult zenResult = zenEngine.execute("get/contract", data);
        if (StringKit.isEmpty(JsonKit.stringify(zenResult.get("field")))) return ZenResult.success();
        List fieldDOs = zenResult.get("field", List.class);
        List<FieldDO> fieldDOList = JsonKit.parseAsList(JsonKit.stringify(fieldDOs), FieldDO.class);
        List<String> partnerIds = new ArrayList<>();
        for (FieldDO fieldDO : fieldDOList) {
            String type = fieldDO.getType();
            if ("date".equals(type)) {
                if (StringKit.isEmpty(fieldDO.getValue())) fieldDO.setValue("无");
                else {
                    Long time = JsonKit.parse(fieldDO.getValue(), long.class);
                    fieldDO.setValue(DateKit.toString(time, "yyyy年MM月dd日"));
                }
            } else if ("partner".equals(type)) {
                partnerIds.add(JsonKit.stringify(fieldDO.getValue()));
            } else if ("table".equals(type)) {
                List<MaterialDO> materialDOS = JsonKit.parseAsList(JsonKit.stringify(fieldDO.getValue()), MaterialDO.class);
                fieldDO.setValue(materialDOS);
            }
        }
        //处理签署人
        List<JsonObject> partyList = zenEngine.selectByIds("party", partnerIds);
        if (partyList != null && !partyList.isEmpty()) {
            for (JsonObject party : partyList) {
                FieldDO fieldDO = FieldDO.findByValue(party.get("id").getAsString(), fieldDOList);
                if (fieldDO != null) fieldDO.setValue(party.get("title").getAsString());
            }
        }
        Map<String, Object> preview = new HashMap<>();
        preview.put("title", zenResult.get("title"));
        preview.put("status", (int) Double.parseDouble(zenResult.get("status")));
        preview.put("context", zenResult.get("context"));
        preview.put("field", fieldDOList);
        return ZenResult.success().setData(preview);
    }
}
